# 获取请求、渲染模板、会话存储、重定向
from flask import Flask, request, render_template, session, redirect

# 导入utils文件中的query.py
from utils import query
# 导入utils文件中的getIndexData所有数据和方法
from utils.getIndexData import *
# 导入utils文件中的getSearchData所有数据和方法
from utils.getSearchData import *
# 导入utils文件中的getTime_tData所有数据和方法
from utils.getTime_tData import *
# 导入utils文件中的getRate_tData所有数据和方法
from utils.getRate_tData import *
# 导入utils文件中的getMap_tData所有数据和方法
from utils.getMap_tData import *
# 导入utils文件中的getType_tData所有数据和方法
from utils.getType_tData import *
# 导入utils文件中的getActor_tData所有数据和方法
from utils.getActor_tData import *
# 导入utils文件中的getTableData所有数据和方法
from utils.getTableData import *
# 导入utils文件中的getComments_cData所有数据和方法
from utils.getComments_cData import *

# 正则
import re

# 注意启动的时候将 FLASK_DEBUG = 0 值改为 FLASK_DEBUG = 1
app = Flask(__name__)
# 设置密钥
app.secret_key = 'This is secret_key you know ?'

# 设置主页面’/‘
@app.route('/')
def main():
    return redirect('/login')

# 登录页面
@app.route('/login', methods=['GET', 'POST'])
def login():  # put application's code here
    if request.method == 'GET':
        return render_template('login.html')
    elif request.method == 'POST':
        request.form = dict(request.form)
        # print(request.form)
        # 定义过滤函数 -- 返回表达式 -- 邮箱Email和Password在item里（item为数据表user查询语句的结果users）
        def filter_fn(item):
            return request.form['email'] in item and request.form['password'] in item
        # users表结果
        users = query.querys('select * from user', [], 'select')
        # 过滤函数 -- 若users中存在Email值和Password值，则记录到filter_user列表中
        filter_user = list(filter(filter_fn, users))
        if len(filter_user):
            # 存储session会话
            session['email'] = request.form['email']
            return redirect('/index')
        else:
            return render_template('error.html', message='邮箱或密码错误')

# 注册页面
@app.route('/register', methods=['GET', 'POST'])
def register():  # put application's code here
    if request.method == 'GET':
        return render_template('register.html')
    elif request.method == 'POST':
        # 将获取到的form数据转换为dict字典
        request.form = dict(request.form)
        # 如果两次密码不同，则跳转error页面
        if request.form['password'] != request.form['passwordChecked']:
            return render_template('error.html', message='两次密码不符')
        # print(request.form)

        # 定义过滤函数 -- 返回表达式 -- 邮箱Email在item里（item为数据表user查询语句的结果users）
        def filter_fn(item):
            return request.form['email'] in item
        # querys(sql, params, type='no_select') -- sql表示sql语句、params表示要传的参数、type表示sql语句类型
        users = query.querys('select * from user', [], 'select')
        # 过滤函数，表示如果邮箱Email在users里，就存储到列表中
        filter_list = list(filter(filter_fn, users))
        # 如果过滤列表有长度，则表示用户已被注册
        if len(filter_list):
            return render_template('error.html', message='该用户已被注册')
        # 否则，将该表单数据插入数据表user中，并重定向到login登录页面
        else:
            # query.querys中的cursor.execute(sql, params)语句
            query.querys('insert into user (email,password) values (%s, %s)', [request.form['email'], request.form['password']])
            return redirect('/login')

# index页面
@app.route('/index', methods=['GET', 'POST'])
def index():
    # 获取在登录时，存储的会话session值email
    email = session.get('email')
    # 获取getIndexData数据
    maxMovieLen, maxRate, maxCasts, maxCountry, typesLen, maxLangLen = getIndexData()
    # 获取getTypesEcharData数据
    typeEcharData = getTypesEcharData()
    # 获取getRateEcharData数据
    row, columns = getRateEcharData()
    # 获取getTableData()数据
    tableData = getTableData()
    return render_template(
        'index.html',
        email=email,
        maxMovieLen=maxMovieLen,
        maxRate=maxRate,
        maxCasts=maxCasts,
        maxCountry=maxCountry,
        typesLen=typesLen,
        maxLangLen=maxLangLen,
        typeEcharData=typeEcharData,
        row=row,
        columns=columns,
        tableData=tableData,
    )

# 电影预告片页面
# /movie/<int:movieId> -- 获取动态路由的编号
@app.route('/movie/<title>')
def movie(title):
    # 获取movie预告片的url
    movieUrl = getMovieUrl(title)
    return render_template('movie.html', movieUrl=movieUrl)

# 搜索页面
# /search/<int:movieId> -- 获取动态路由的编号
@app.route('/search/<int:movieId>', methods=['GET', 'POST'])
def search(movieId):
    # 获取在登录时，存储的会话session值email
    email = session.get('email')
    # 获取数据 -- 和当前movieId匹配的id所在的行，即所有信息
    if request.method == 'GET':
        resultData = getMovieDetailData(movieId)
    else:
        request.form = dict(request.form)
        # 获取数据 -- 匹配数据表中含有表单返回的关键字
        resultData = getMovieDetailSearchWordData(request.form['searchWord'])
    return render_template('search.html', resultData=resultData, email=email)

# 时间分析表页面
@app.route('/time_t')
def time_t():
    # 获取在登录时，存储的会话session值email
    email = session.get('email')
    # 获取电影年份数据
    row, columns = getYearData()
    # 获取电影时间分布数据
    movieTimeData = getMovieTimeData()
    print(movieTimeData)
    return render_template('time_t.html', email=email, row=row, columns=columns, movieTimeData=movieTimeData)

# 评分分析表页面
@app.route('/rate_t/<type>', methods=['GET', 'POST'])
def rate_t(type):
    # 获取在登录时，存储的会话session值email
    email = session.get('email')
    # 获取所有电影类型数据
    typeList = getAllTypes()
    # 获取所有电影评分即各评分个数
    row, colunms = getAllRateDataByType(type)
    # 获取搜索框的电影名称关键字 -- 并获取stars评分星级 -- 5星到1星
    # 只返回查询到的第一条信息
    if request.method == 'GET':
        starsData, searchName = getStars('肖申克的救赎')
    else:
        request.form = dict(request.form)
        starsData, searchName = getStars(request.form['searchIpt'])
    # 获取柱形图横纵坐标 -- （电影年份，电影评分均值）
    yearRow, meanRateColumns = getYearMeanData()
    return render_template(
        'rate_t.html',
        email=email,
        typeList=typeList,
        type=type,
        row=row,
        colunms=colunms,
        starsData=starsData,
        searchName=searchName,
        yearRow=yearRow,
        meanRateColumns=meanRateColumns
    )

# 地图分析表页面
@app.route('/map_t')
def map_t():
    # 获取在登录时，存储的会话session值email
    email = session.get('email')
    # 电影地区及其个数
    row, colunms = getMapData()
    # 电影语言及其个数
    langRow, langColunms = getLangData()
    return render_template(
        'map_t.html',
        email=email,
        row=row,
        colunms=colunms,
        langRow=langRow,
        langColunms=langColunms
    )

# 类型分析表页面
@app.route('/type_t')
def type_t():
    # 获取在登录时，存储的会话session值email
    email = session.get('email')
    # 获取电影类型数据 -- 电影类型及其个数
    typesList = getTypesData()
    return render_template(
        'type_t.html',
        email=email,
        typesList=typesList
    )

# 导演与演员分析表页面
@app.route('/actor_t')
def actor_t():
    # 获取在登录时，存储的会话session值email
    email = session.get('email')
    # 获取导演电影数量数量Top20
    directors, cnts = getDirectorsData()
    # 获取演员参演电影数量数量Top20
    casts, nums = getDirectorsData()
    return render_template(
        'actor_t.html',
        email=email,
        directors=directors,
        cnts=cnts,
        casts=casts,
        nums=nums
    )

# 数据表操作页面
@app.route('/table/<title>')
def table(title):
    # 获取在登录时，存储的会话session值email
    email = session.get('email')
    # 获取操作表数据
    tableData = getTableDataById()
    # 如果点击了删除，即获取到的title等于当前行的电影名称，则删除当前数据，并重定向到数据操作表页面
    if title != '0':
        delMovieByTitle(title)
        return redirect('/table/0')
    return render_template('table.html', email=email, tableData=tableData)

# 评论词云图页面
@app.route('/comments_c', methods=['GET', 'POST'])
def comments_c():
    # 获取在登录时，存储的会话session值email
    email = session.get('email')
    if request.method == 'GET':
        return render_template('comments_c.html', email=email)
    else:
        # 获取词云图图片文件地址
        # dict(request.form)['searchIpt'] -- 将请求的表单结果转换为字典，并取出搜索关键字
        # print(dict(request.form))
        # print(dict(request.form)['searchIpt'])
        resSrc, searchName = getCommentsImage(dict(request.form)['searchIpt'])
        return render_template('comments_c.html', email=email, resSrc=resSrc, searchName=searchName)

# 标题词云图页面
@app.route('/title_c')
def title_c():
    # 获取在登录时，存储的会话session值email
    email = session.get('email')
    titleImg = getTitleImage()
    return render_template('title_c.html', email=email, titleImg=titleImg)

# 简介词云图页面
@app.route('/summary_c')
def summary_c():
    # 获取在登录时，存储的会话session值email
    email = session.get('email')
    summaryImage = getSummaryImage()
    return render_template('summary_c.html', email=email, summaryImage=summaryImage)

# 演员名称词云图页面
@app.route('/casts_c')
def casts_c():
    # 获取在登录时，存储的会话session值email
    email = session.get('email')
    castsImage = getCastsImage()
    return render_template('casts_c.html', email=email, castsImage=castsImage)

# 登出页面
@app.route('/logout')
def logout():
    # 清空存储的session值
    session.clear()
    # 重定向到登录页面
    return redirect('/login')

# 导航守卫 -- 生命周期函数，在请求前执行
@app.before_request
def before_request():
    pat = re.compile(r'^/static')
    # 如果匹配的路径是以/static为开头的，则跳过
    if re.search(pat, request.path):
        return
    # 如果匹配的路径为/login，则跳过
    if request.path == '/login':
        return
    # 如果匹配的路径为/register，则跳过
    if request.path == '/register':
        return
    # 如果email存在，则跳过
    email = session.get('email')
    if email:
        return None
    # 否则，重定向到/login页面
    return redirect('/login')

if __name__ == '__main__':
    app.run()
